const db = wx.cloud.database();
const GreenHouseCollection = db.collection('Greenhouse_Data');
const wxCharts = require('../../libs/wxcharts-min'); // 引入wxCharts库

Page({
  data: {
    actions: [],
    result: "",
    loading: false,
    show: false,
    imageUrl: "",
    debugInfo: "",
    retryCount: 0,
    probabilities: [], // 所有病害的置信度（百分比）
    top4Data: [], // 置信度前4的病害数据（名称+置信度）
    advice: "", // 存储AI生成的建议
    // 完整的病害列表，与服务器返回的all_predictions键名对应
    classes: [
      "健康", "叶枯病", "叶蝉虫害", "病毒性病害", 
      "白粉病", "营养缺乏症", "葡萄座腔菌病", 
      "葡萄瘿螨", "褐斑病", "霜霉病", "黑腐病"
    ],
    colors: ['#bce4ad', '#FF9800', '#E53935', '#9C27B0', '#2196F3'],
    // 音频相关状态（已修复重复定义问题）
    cancelRequest: false,   // 是否取消语音请求
    audioPlaying: false,    // 是否正在播放音频
    tempPcmPath: '',        // 临时PCM文件路径
    tempWavPath: '',         // 临时WAV文件路径
    AIloading: false, // 新增：控制语音合成加载状态
  },

  // 大棚录像数据加载
  onLoad() {
    this.loadData();
     // 初始化音频上下文（全局唯一，减少内存占用）
     this.initAudioContext();
  },

  async loadData() {
    try {
      const res = await GreenHouseCollection.get();
      const rawData = res.data;
      
      // 按greenhouseID分组，保留最新时间记录
      const groupedData = {};
      rawData.forEach(item => {
        const key = item.greenhouseID;
        const currentTime = item.monitortime;
        if (groupedData[key]) {
          const existingTime = groupedData[key].monitortime;
          if (currentTime > existingTime) {
            groupedData[key] = item;
          }
        } else {
          groupedData[key] = item;
        }
      });
      
      // 整理字段并更新数据
      const newData = Object.values(groupedData).map(item => ({
        greenhouseID: item.greenhouseID,
        temperature: item.temperature,
        humidity: item.humidity,
        light: item.light,
        gasCO2: item['gas(CO2)'],
        monitorTime: item.monitortime,
        video: item.vedio // 修正拼写错误
      }));
      this.setData({
        actions: this.data.actions.concat(newData)
      });
    } catch (e) {
      console.error('获取大棚数据失败', e);
      this.setData({ loading: false });
    }
  },

  async onSelect(e) {
    const selectedData = e.target.dataset.news;
    const greenhouseId = selectedData.greenhouseID;
    wx.navigateTo({
      url: `/pages/monitoring/monitoring?greenhouseId=${greenhouseId}`
    });
  },

  // 病虫害检测模块
  takePhotoOrCamera() {
    wx.showActionSheet({
      itemList: ['拍照', '从相册选择'],
      success: (res) => {
        if (res.tapIndex === 0) {
          this.takePhoto();
        } else if (res.tapIndex === 1) {
          this.chooseAlbumImage();
        }
      }
    });
  },

  takePhoto() {
    this.chooseImage("camera");
  },

  chooseAlbumImage() {
    this.chooseImage("album");
  },

  chooseImage(sourceType) {
    wx.chooseImage({
      count: 1,
      sizeType: ["compressed"],
      sourceType: [sourceType],
      success: (res) => {
        this.uploadToCloud(res.tempFilePaths[0]);
      },
      fail: (err) => {
        this.logDebug('选择图片失败: ' + JSON.stringify(err));
        wx.showToast({ title: "选择图片失败", icon: "none" });
      }
    });
  },

  // 新增：调用蓝心小V AI生成防治建议
  async getAIDiagnosisAdvice(diseaseName) {
    try {
      // 构造提示词，明确要求AI生成专业建议
      const prompt = `
        请针对葡萄的“${diseaseName}”提供专业的防治建议，内容包括：
        1. 发病原因或常见诱因；
        2. 具体防治措施（如药剂选择、使用方法、频率）；
        3. 预防措施（如种植管理、环境控制等）。
        要求语言简洁明了，适合农业从业者参考，总字数控制在200字以内。
      `;

      // 调用蓝心小V AI云函数
      const result = await wx.cloud.callFunction({
        name: 'BlueLM-70BAPI', // 蓝心小V AI云函数名称
        data: { prompt }
      });

      // 提取并处理AI返回结果（确保是字符串）
      const aiAdvice = result.result.data?.toString().trim() || '未获取到有效建议';
      return aiAdvice;
    } catch (error) {
      this.logDebug(`AI建议生成失败: ${error.message}`);
      return '建议生成失败，请重试';
    }
  },

  async uploadToCloud(tempFilePath) {
    this.setData({ loading: true });
    this.logDebug('开始上传...');
  
    try {
      // 1. 上传图片到云存储
      const uploadRes = await wx.cloud.uploadFile({
        cloudPath: `pest_images/${Date.now()}.jpg`,
        filePath: tempFilePath
      });
      this.logDebug('上传成功，fileID: ' + uploadRes.fileID);
  
      // 2. 获取临时URL（用于展示图片）
      const getTempUrlRes = await wx.cloud.getTempFileURL({
        fileList: [uploadRes.fileID]
      });
      const imageUrl = getTempUrlRes.fileList[0].tempFileURL;
  
      // 3. 调用病虫害检测云函数
      const cloudRes = await wx.cloud.callFunction({
        name: "pest_detection",
        data: { fileID: uploadRes.fileID }
      });
      this.logDebug('云函数返回: ' + JSON.stringify(cloudRes.result));
  
      // 4. 处理检测结果
      if (cloudRes.result.success && cloudRes.result.result) {
        // 从 cloudRes.result.result 中提取检测数据
        const detectionResult = cloudRes.result.result; 
        
        // 提取所有病虫害的置信度
        const probabilities = this.data.classes.map(className => 
          detectionResult.all_predictions[className] || 0
        );

        // 关联病害名称和置信度，生成数组
        const diseaseWithProb = this.data.classes.map((name, index) => ({
          name,
          value: probabilities[index]
        }));

        // 按置信度从高到低排序，取前4
        const top4 = diseaseWithProb.sort((a, b) => b.value - a.value).slice(0, 4);
        const top4Formatted = top4.map(item => ({
          name: item.name,
          value: (item.value * 100).toFixed(1) // 转换为百分比
        }));

        // 找到最高置信度的病害
        const maxIndex = probabilities.indexOf(Math.max(...probabilities));
        const top1Prediction = this.data.classes[maxIndex];
        
        // 5. 获取对应的防治建议（通过AI生成）
        let adviceText = "";
        if (top1Prediction === "健康") {
          adviceText = "当前植株很健康，无需进行调整。建议保持现有种植管理方式，定期监测生长状态即可。";
        } else {
          // 调用AI生成病害建议
          adviceText = await this.getAIDiagnosisAdvice(top1Prediction);
        }

        // 更新页面数据
        this.setData({
          result: `检测结果：${top1Prediction}（置信度：${(detectionResult.confidence * 100).toFixed(1)}%）`,
          show: true,
          imageUrl: imageUrl,
          advice: adviceText, // 更新为AI生成的建议
          top4Data: top4Formatted,
          loading: false
        });

        // 绘制图表
        this.drawTop4Chart();
      } else {
        this.setData({ 
          advice: "无有效检测结果，请重试",
          show: true,
          loading: false
        });
      }
    } catch (err) {
      this.logDebug('处理失败: ' + err.message);
      wx.showToast({ title: err.message, icon: "none" });
      this.setData({ 
        advice: "操作失败，请检查网络或重试",
        loading: false
      });
    } finally {
      this.setData({ loading: false });
    }
  },

  // 绘制前4高置信度的图表（柱状图）
  drawTop4Chart() {
    const top4 = this.data.top4Data;
    if (top4.length === 0) return; // 确保有数据再绘制
    
    // 提取图表所需数据（病害名称、置信度数值）
    const categories = top4.map(item => item.name); // X轴标签（病害名称）
    const data = top4.map(item => parseFloat(item.value)); // Y轴数据（置信度百分比）

    // 获取画布宽度（自适应屏幕）
    const query = wx.createSelectorQuery();
    query.select('#top4ChartContainer').boundingClientRect(rect => {
      const width = rect?.width || 350; // 容器宽度，默认350px
      const height = 250; // 图表高度

      // 初始化柱状图
      new wxCharts({
        canvasId: 'top4Chart', // 对应WXML中的canvas-id
        type: 'column', // 图表类型：柱状图
        categories: categories, // X轴：病害名称
        series: [
          {
            name: '置信度（%）', // 数据系列名称
            data: data, // 置信度数值
            color: this.data.colors[1], // 柱状图颜色
            format: (val) => `${val}%` // 数据标签格式化（显示百分比）
          }
        ],
        dataLabel: true, // 显示每个柱子的数值标签
        legend: false, // 柱状图无需图例（X轴已显示名称）
        yAxis: {
          title: '置信度（%）', // Y轴标题
          min: 0, // Y轴最小值（从0开始，确保比例正确）
          max: Math.max(...data) * 1.2, // Y轴最大值（留20%余量）
          format: (val) => `${val}%` // Y轴刻度显示百分比
        },
        xAxis: {
          disableGrid: false, // 显示X轴网格线
          axisLine: true // 显示X轴轴线
        },
        width: width, // 图表宽度
        height: height, // 图表高度
        animation: true, // 启用加载动画
        background: '#FFF' // 图表背景色
      });
    }).exec();
  },

  logDebug(info) {
    console.log('[DEBUG]', info);
    this.setData({ debugInfo: `${new Date().toLocaleTimeString()} ${info}` });
  },

  onClose() {
    this.setData({ show: false, retryCount: 0 });
  },

  // 语音播报
  /**
   * 初始化音频上下文（复用逻辑，避免重复创建）
   */
  initAudioContext() {
    if (!this.audioCtx) {
      this.audioCtx = wx.createInnerAudioContext();
      // 监听音频自然结束
      this.audioCtx.onEnded(() => {
        this.setData({ audioPlaying: false });
        this.cleanupAudio(); // 播放结束后清理资源
      });
      // 监听手动停止
      this.audioCtx.onStop(() => {
        this.setData({ audioPlaying: false });
        this.cleanupAudio();
      });
      // 监听播放错误
      this.audioCtx.onError((err) => {
        console.error('音频播放失败:', err);
        wx.showToast({ title: '播放失败', icon: 'none' });
        this.setData({ audioPlaying: false });
        this.cleanupAudio();
      });
    }
  },

  /**
   * 点击语音图标，调用服务器合成音频并播放
   */
  synthesizeSpeech() {
    const text = this.data.advice;
    // 文本为空校验
    if (!text.trim()) {
      wx.showToast({ title: '暂无AI建议内容', icon: 'none' });
      return;
    }
    // 文本长度限制（防止音频过大）
    const MAX_TEXT_LENGTH = 500;
    if (text.length > MAX_TEXT_LENGTH) {
      wx.showToast({
        title: `文本过长（超过${MAX_TEXT_LENGTH}字）`,
        icon: 'none'
      });
      return;
    }
    // 防止重复请求
    if (this.data.AIloading) return;

    this.setData({ 
      AIloading: true, 
      cancelRequest: false,
      audioPlaying: false 
    });

    // 保存请求任务，支持取消
    this.speechRequestTask = wx.request({
      url: 'http://82.157.209.238:5000/api/tts', // 已改为HTTPS（必须）
      method: 'POST',
      data: { text: text },
      header: { 'Content-Type': 'application/json' },
      timeout: 60000, // 超时时间60秒
      success: (res) => {
        if (this.data.cancelRequest) return; // 已取消则不处理

        if (res.data.success) {
          // 成功获取音频，调用播放方法
          this.playAudio(res.data.audio_base64);
        } else {
          wx.showToast({
            title: res.data.error || '语音合成失败',
            icon: 'none'
          });
        }
      },
      fail: (err) => {
        if (this.data.cancelRequest) return;

        console.error('语音合成接口调用失败:', err);
        // 细化错误提示
        let errorMsg = '网络请求失败';
        if (err.errMsg.includes('timeout')) {
          errorMsg = '合成超时，请稍后重试';
        } else if (err.errMsg.includes('ssl') || err.errMsg.includes('http')) {
          errorMsg = '请使用HTTPS协议';
        }
        wx.showToast({ title: errorMsg, icon: 'none' });
      },
      complete: () => {
        if (!this.data.cancelRequest) {
          this.setData({ AIloading: false });
        }
      }
    });
  },

  /**
   * 取消语音合成请求
   */
  cancelSynthesis() {
    if (this.data.AIloading && this.speechRequestTask) {
      this.speechRequestTask.abort(); // 终止请求
      this.setData({ 
        AIloading: false, 
        cancelRequest: true,
        audioPlaying: false 
      });
      wx.showToast({ title: '已取消合成', icon: 'none' });
    }
  },

  /**
   * 播放音频（处理Base64格式音频）
   */
  playAudio(base64Data) {
    // 移除Base64前缀
    const pureBase64 = base64Data.replace(/^data:audio\/\w+;base64,/, '');
    // 转换为ArrayBuffer
    const buffer = wx.base64ToArrayBuffer(pureBase64);

    // 生成临时文件路径并记录
    const timestamp = Date.now();
    const tempPcmPath = `${wx.env.USER_DATA_PATH}/tts_${timestamp}.pcm`;
    const tempWavPath = `${wx.env.USER_DATA_PATH}/tts_${timestamp}.wav`;
    this.setData({ tempPcmPath, tempWavPath });

    // 写入PCM文件
    const fs = wx.getFileSystemManager();
    fs.writeFile({
      filePath: tempPcmPath,
      data: buffer,
      encoding: 'binary',
      success: () => {
        // 转换为WAV并播放
        this.convertPcmToWav(tempPcmPath, tempWavPath, () => {
          this.audioCtx.src = tempWavPath;
          this.audioCtx.play();
          this.setData({ audioPlaying: true }); // 标记播放中
        });
      },
      fail: (err) => {
        console.error('音频文件写入失败:', err);
        wx.showToast({ title: '音频处理失败', icon: 'none' });
        this.cleanupAudio(); // 失败时清理
      }
    });
  },

  /**
   * 停止当前播放
   */
  stopAudio() {
    if (this.audioCtx && this.data.audioPlaying) {
      this.audioCtx.stop();
      this.setData({ audioPlaying: false });
    }
  },

  /**
   * PCM转WAV（优化数据复制效率）
   */
  convertPcmToWav(pcmPath, wavPath, callback) {
    const fs = wx.getFileSystemManager();
    fs.readFile({
      filePath: pcmPath,
      success: (res) => {
        const pcmData = res.data;
        const sampleRate = 24000; // 与服务器采样率一致
        const bitDepth = 16; // 16位采样
        const numChannels = 1; // 单声道

        // 构建WAV文件头（44字节）
        const buffer = new ArrayBuffer(44 + pcmData.byteLength);
        const view = new DataView(buffer);

        // RIFF chunk
        view.setUint8(0, 0x52); // 'R'
        view.setUint8(1, 0x49); // 'I'
        view.setUint8(2, 0x46); // 'F'
        view.setUint8(3, 0x46); // 'F'
        view.setUint32(4, 36 + pcmData.byteLength, true);
        view.setUint8(8, 0x57); // 'W'
        view.setUint8(9, 0x41); // 'A'
        view.setUint8(10, 0x56); // 'V'
        view.setUint8(11, 0x45); // 'E'

        // fmt subchunk
        view.setUint8(12, 0x66); // 'f'
        view.setUint8(13, 0x6d); // 'm'
        view.setUint8(14, 0x74); // 't'
        view.setUint8(15, 0x20); // ' '
        view.setUint32(16, 16, true); // PCM格式
        view.setUint16(20, 1, true); // 线性PCM
        view.setUint16(22, numChannels, true);
        view.setUint32(24, sampleRate, true);
        view.setUint32(28, sampleRate * numChannels * (bitDepth / 8), true);
        view.setUint16(32, numChannels * (bitDepth / 8), true);
        view.setUint16(34, bitDepth, true);

        // data subchunk
        view.setUint8(36, 0x64); // 'd'
        view.setUint8(37, 0x61); // 'a'
        view.setUint8(38, 0x74); // 't'
        view.setUint8(39, 0x61); // 'a'
        view.setUint32(40, pcmData.byteLength, true);

        // 优化：批量复制PCM数据（替代for循环）
        const pcmView = new Uint8Array(pcmData);
        const wavView = new Uint8Array(buffer);
        wavView.set(pcmView, 44); // 从第44字节开始写入

        // 写入WAV文件
        fs.writeFile({
          filePath: wavPath,
          data: buffer,
          encoding: 'binary',
          success: callback,
          fail: (err) => {
            console.error('WAV文件转换失败:', err);
            wx.showToast({ title: '音频格式转换失败', icon: 'none' });
            this.cleanupAudio(); // 失败时清理
          }
        });
      },
      fail: (err) => {
        console.error('读取PCM文件失败:', err);
        this.cleanupAudio(); // 失败时清理
      }
    });
  },

  /**
   * 清理音频资源（删除临时文件+重置状态）
   */
  cleanupAudio() {
    const { tempPcmPath, tempWavPath } = this.data;
    const fs = wx.getFileSystemManager();

    // 尝试删除临时文件（忽略删除失败的错误）
    if (tempPcmPath) {
      try { fs.unlinkSync(tempPcmPath); } catch (e) { /* 忽略错误 */ }
    }
    if (tempWavPath) {
      try { fs.unlinkSync(tempWavPath); } catch (e) { /* 忽略错误 */ }
    }

    // 重置临时文件路径
    this.setData({
      tempPcmPath: '',
      tempWavPath: ''
    });
  },
  onUnload() {
    // 销毁音频上下文，释放资源
    if (this.audioCtx) {
      this.audioCtx.destroy();
      this.audioCtx = null;
    }
    // 确保临时文件被删除
    this.cleanupAudio();
  }
});